//
//  MyTableView.swift
//  MySwiftUIDemo
//
//  Created by dn56-macbook on 2025/3/17.
//

import SwiftUI

//小号 170*170
//中号 364 * 170
//大号 364 * 382
struct MyTableView: View {
    @State private var listData: [Item] = []
    @State private var listDataInfo: [ItemInfo] = []
    @State private var currentPage: Int = 0
    @State var isLogo: Bool = false
    var body: some View {
        ZStack{
            Color.white
            GeometryReader { geo in
                let w = geo.size.width
                let h = geo.size.height
                let r = Task().getR(w<h)
                ScrollView(.vertical,showsIndicators: false) {

                    LazyVStack(alignment: .leading,spacing: 15) {
                        ForEach(listDataInfo.indices,id: \.self) { index in
                            let objc = listDataInfo[index]
                            let list = getCellItem(objc.listData)
                            ContentCell(listData: list,number: w < h ? 12 : 16).frame(width: geo.size.width,height: 410*r).id("\(list)")
                        }
                    }.id("\(w)-\(h)")
                }.onAppear {
                    self.listData = getData()
                    debugPrint("===",geo.size.width/4-75/4)
                    loadData(w < h)
                }.onChange(of: w > h) { oldValue, newValue in
                    loadData(w < h)
                }
            }
        }
    }
    func getCellItem(_ listData:[Item])->[[Item]]{
        let sum = task.getSum(listData)
        let have1 = task.haveData(listData, sum: 1)
        let have2 = task.haveData(listData, sum: 2)
        let have4 = task.haveData(listData, sum: 4)
        if listData.count == 8 && sum == 12 && have1 == 3 && have2 == 3{//竖屏 sm sm sm sm
            let lis = task.getDatas(listData, sum: 1)
            let lim = task.getDatas(listData, sum: 2)
            var listData :[[Item]] = []
            let lipre1 = Array(lis.prefix(2) + lim.prefix(2))
            let lisuf1 = Array(lis.suffix(2) + lim.suffix(2))
            listData.append(lipre1)
            listData.append(lisuf1)
            return listData
        }else if listData.count == 7 && sum == 12 && have1 == 4 && have2 == 2 && have4 == 1{//shup sm sm ssl
            let lis = task.getDatas(listData, sum: 1)
            let lim = task.getDatas(listData, sum: 2)
            let lil = task.getDatas(listData, sum: 4)
            var listData :[[Item]] = []
            let lipre1 = Array(lis.prefix(2) + lim.prefix(2))
            let lisuf1 = Array(lis.suffix(2) + lil.prefix(1))
            listData.append(lipre1)
            listData.append(lisuf1)
            return listData
            
        }else if listData.count == 9 && sum == 16 && have1 == 4 && have2 == 4 && have4 == 1{//横屏 sm sm sm sm l
            let lis = task.getDatas(listData, sum: 1)
            let lim = task.getDatas(listData, sum: 2)
            let lil = task.getDatas(listData, sum: 4)
            var listData :[[Item]] = []
            let lipre1 = Array(lis.prefix(2) + lim.prefix(2))
            let lisuf1 = Array(lis.suffix(2) + lim.suffix(2))
            let lisufL = Array(lil.suffix(1))
            listData.append(lipre1)
            listData.append(lisuf1)
            listData.append(lisufL)
            return listData
            
        }else if listData.count ==  10 && sum == 16 && have1 == 4 && have2 == 6{//横屏 sm sm sm sm mm
            
            let lis = task.getDatas(listData, sum: 1)
            let lim = task.getDatas(listData, sum: 2)
            let list4 = lim.prefix(4)
            var listData :[[Item]] = []
            let lipre1 = Array(lis.prefix(2) + lim.prefix(2))
            let lisuf1 = Array(lis.suffix(2) + list4.suffix(2))
            let lisufL = Array(lim.suffix(2))
            listData.append(lipre1)
            listData.append(lisuf1)
            listData.append(lisufL)
            return listData
        }else if listData.count == 12 && sum == 16 && have1 == 8 && have2 == 4{//横屏 sm sm sm sm ssss
            let lis = task.getDatas(listData, sum: 1)
            let lim = task.getDatas(listData, sum: 2)
            let list4 = lis.prefix(4)
            var listData :[[Item]] = []
            let lipre1 = Array(lis.prefix(2) + lim.prefix(2))
            let lisuf1 = Array(lis.suffix(2) + list4.suffix(2))
            let lisufL = Array(lis.suffix(4))
            listData.append(lipre1)
            listData.append(lisuf1)
            listData.append(lisufL)
            return listData
        }
        else if listData.count == 11 && sum == 16 && have1 == 6 && have2 == 5{//横屏 sm sm sm sm ssm
            let lis = task.getDatas(listData, sum: 1)
            let lim = task.getDatas(listData, sum: 2)
            let list4 = lis.prefix(4)
            let listM = lis.prefix(4)
            var listData :[[Item]] = []
            let lipre1 = Array(list4.prefix(2) + listM.suffix(2))
            let lisuf1 = Array(list4.suffix(2) + listM.suffix(2))
            let lisufL = Array(lis.suffix(2)) +  Array(lim.suffix(1))
            listData.append(lipre1)
            listData.append(lisuf1)
            listData.append(lisufL)
            return listData
        }
        else{
            let list = task.create2DArray(with: listData, targetSum: 8)
            var listNewModel: [[Item]] = []
            list.forEach { listItem in
                let sum = task.getSum(listItem)
                if sum == 8 && listItem.count == 1{
                    listNewModel.append(listItem)
                }else if sum == 4 && listItem.count == 1{
                    listNewModel.append(listItem)
                }
                else if listItem.count > 1{
                    let li = task.create2DArray(with: listItem, targetSum: 4)
                    listNewModel.append(contentsOf: li)
                }
            }
            return listNewModel
        }
    }
    // 12
    // 12
    let task = Task()
    func getData()-> [Item]{
        var list: [Item] = []
        let listData =  [Item(width: 1,height: 1),Item(width: 1,height: 1), Item(width: 2,height: 1),Item(width: 2,height: 1),Item(width: 2,height: 2)]
        for i in 0...25{
//            let index = Int(arc4random_uniform(100))%listData.count
//            var item = listData[index]
//            item.name = "\(i + 1)"
            list.append(contentsOf: listData)
        }
        return list
    }
    func loadData(_ port: Bool){
        debugPrint("========isLaunchLeft",!port)
        self.listDataInfo.removeAll()
        let number = port ? 12 : 16
        let list = self.listData
        let result = task.create2DArray(with: list, targetSum: number)
        result.forEach { listData in
            debugPrint("=====",listData.count)
            let info = ItemInfo(listData: listData,count: task.getSum(listData))
            self.listDataInfo.append(info)
        }
        debugPrint(listDataInfo.count)

    }
    func spaceData(){

    }
}
struct ContentCell: View {
    var listData: [[Item]]
    var number : Int

    var body: some View {
        let r = Task().getR(number == 12)
        ZStack{
            Color.clear
            HStack(spacing: 15) {
                ForEach(listData.indices, id: \.self) { index in
                    let list = listData[index]
                    let width = getWidth(list)
                    ContentItemCell(r: r, listData: list).frame(width: width,height: 410*r)
                }
                if getTotalSum(listData) <= number - 4{
                    Spacer(minLength: 0.01)
                }
                //Spacer(minLength: 0.01)
            }.padding(.horizontal,15)
        }
    }
    func getSum(_ listData: [Item])->Int{
        var sum = 0
        listData.forEach { item in
            sum = sum + item.width * item.height
        }
        return sum
    }
    func getTotalSum(_ listData: [[Item]])->Int{
        let list = listData.flatMap({$0})
        return getSum(list)
    }
    func getWidth(_ item: [Item])->CGFloat{
        let r = Task().getR(number == 12)
        let sum = getSum(item)
        if sum == 8{
            return 743*r
        }else if sum == 6{
            return 560*r
        }
        return 364.0*r
    }
}
struct ContentItemCell: View {
    var r: CGFloat
    @State var listData: [Item] = []
    func getSum()->Int{
        var sum = 0
        listData.forEach { item in
            sum = sum + item.width * item.height
        }
        return sum
    }
    var body: some View {
        ZStack{
            Color.clear
            let sum = getSum()
            if listData.count == 1 && sum == 8{//超大号
                let item = listData[0]
                getExLargetView(item)
            }else if listData.count == 1 && sum == 4{//大号
                let item = listData[0]
                getLargetView(item)
            }else if listData.count == 4 && sum == 6{
                get6View()
            }else if listData.count == 3 && sum == 6{
                get6View()
            }
            else{
                getOtherView()
            }
        }
    }
    @ViewBuilder
    func get6View()->some View{
        if listData.count == 4{
            VStack(spacing: 20*r) {
                HStack(spacing: 15) {
                    getsmallView(getData(1, index: 0))
                    getMediumView(getData(2, index: 0))
                }
                HStack(spacing: 15) {
                    getsmallView(getData(1, index: 1))
                    getMediumView(getData(2, index: 1))
                }
            }
        }else if listData.count == 3{
            HStack(alignment: .center, spacing: 20*r) {
                VStack(spacing: 20*r) {
                    getsmallView(getData(1, index: 0))
                    getsmallView(getData(1, index: 1))
                }
                getLargetView(getData(4, index: 0))
            }
        }
    }
    // 12 12
    // 11 4
    //4 2 2 1 1 1 1
    @ViewBuilder
    func getOtherView()->some View{
        ZStack{
            Color.clear
            if getSum() == 4{
                if listData.count == 2{
                    VStack(spacing: 15) {
                        getMediumView(listData[0])
                        getMediumView(listData[1])
                    }
                }else if listData.count == 4{
                    VStack(alignment: .center, spacing: 15) {
                        HStack(alignment: .center, spacing: 15) {
                            getsmallView(listData[0])
                            getsmallView(listData[1])
                        }
                        HStack(alignment: .center, spacing: 15) {
                            getsmallView(listData[2])
                            getsmallView(listData[3])
                        }
                    }
                }else if listData.count == 3{
                    let list = getNewData(listData)
                    VStack(alignment: .center, spacing: 15) {
                        getMediumView(list[0])
                        HStack(alignment: .center, spacing: 15) {
                            getsmallView(list[1])
                            getsmallView(list[2])
                        }
                    }
                }else if  listData.count == 2{
                    ZStack{
                        Color.green
                    }
                }
            }else if getSum() == 3{
                if listData.count == 3{
                    VStack(alignment: .center, spacing: 15) {
                        HStack(alignment: .center, spacing: 15) {
                            getsmallView(listData[0])
                            getsmallView(listData[1])
                        }
                        HStack(alignment: .center, spacing: 15) {
                            getsmallView(listData[2])
                            Spacer()
                        }
                    }
                }else if listData.count == 2{
                    let list = getNewData(listData)
                    VStack(alignment: .center, spacing: 15) {
                        getMediumView(list[0])
                        HStack(alignment: .center, spacing: 15) {
                            getsmallView(list[1])
                            Spacer()
                        }
                    }
                }
            }else if getSum() == 2{
                if listData.count == 2{
                    VStack(alignment: .center, spacing: 15) {
                        HStack(alignment: .center, spacing: 15) {
                            getsmallView(listData[0])
                            getsmallView(listData[1])
                        }
                        Spacer()
                    }
                }else if listData.count == 1{
                    VStack(alignment: .center, spacing: 15) {
                        getMediumView(listData[0])
                        Spacer()
                    }
                }
            }else if getSum() == 1{
                VStack(alignment: .center, spacing: 15) {
                    HStack(alignment: .center, spacing: 15) {
                        getsmallView(listData[1])
                        Spacer()
                    }
                    Spacer()
                }
            }
        }.frame(width: 364*r).clipped()
    }
    func getExLargetView(_ item: Item)->some View{
        ZStack{
            Color.blue.frame(width: 743*r,height: 382*r)
            Text("\(item.name)").foregroundColor(.white)
        }
    }
    func getLargetView(_ item: Item)->some View{
        ZStack{
            Color.red.frame(width: 364*r,height: 382*r)
            Text("\(item.name)").foregroundColor(.white)
        }
    }
    func getMediumView(_ item: Item)-> some View{
        ZStack{
            Color.yellow.frame(width: 364*r,height: 170*r)
            Text("\(item.name)").foregroundColor(.white)
        }
    }
    func getsmallView(_ item: Item)->some View{
        ZStack{
            Color.gray.frame(width: 170*r,height: 170*r)
            Text("\(item.name)").foregroundColor(.white)
        }
    }
    func getNewData(_ listData: [Item])->[Item]{
        let newData: [Item] = listData.filter { item in
            return item.width * item.height == 2
        }
        var list = listData
        list.removeAll { item in
            return item.width * item.height == 2
        }
        list.insert(contentsOf: newData, at: 0)
        return list
    }
    func getData(_ sum: Int,index: Int)->Item{
        let list = listData.filter { objc in
            return objc.width * objc.height == sum
        }
        return list[index]
    }
    func getWidth(_ item: Item)->CGFloat{
        let width = (item.height * item.width  == 1) ? 170.0*r : 364.0*r
        return width
    }
}
//12
//8 + 4
//8 + 2 + 2
//8 + 2 + 1 + 1
//8 + 1 + 1 + 1 + 1
//4 4
//4 + 2 + 2
//4 + 2 + 1 + 1
//4 + 1 + 1 + 1

//16
// 8 + 8
// 8 + 4 + 4
// 8 + 4 + 2 + 2
// 8 + 4 + 2 + 1 + 1
// 8 + 4 + 1 + 1 + 1 + 1
